using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text.RegularExpressions;
using System;

using Orchard.ContentManagement;
using Orchard.Core.Navigation.Models;
using Orchard.Core.Navigation.Services;
using Orchard.Core.Navigation.ViewModels;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Mvc.AntiForgery;
using Orchard.UI;
using Orchard.UI.Navigation;
using Orchard.Utility;
using Orchard;

using Redirect404.ViewModels;
using Redirect404.Services;
using Redirect404.Models;


namespace Redirect404.Controllers {
    public class RedirectController : Controller {
        private readonly IRedirectService _redirectService;
        public IOrchardServices Services { get; set; }

        public RedirectController(IRedirectService redirectService, IOrchardServices services) {
            _redirectService = redirectService;
            Services = services;
            T = NullLocalizer.Instance;
        }

        [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
        public ActionResult Lookup(string aspxErrorPath, string loopStopper)
        {
            List<RedirectItemEntry> redirectPaths = _redirectService.Get().Select(CreateRedirectItemEntries).OrderBy(redirectPartEntry => redirectPartEntry.ProcessOrder).ToList();

            if (loopStopper == "1")
            {
                throw new HttpException(404, "NotFound");
            }

            foreach (RedirectItemEntry redirectItem in redirectPaths)
            {
                if (redirectItem.UseRegex)
                {
                    Match urlMatch = Regex.Match(aspxErrorPath, redirectItem.RequestedURL, RegexOptions.IgnoreCase);
                    
                    if(urlMatch.Success)
                    {
                        List<String> matchValues = new List<string>();
                        int matchCount = 0;
                        foreach(Group thisGroup in urlMatch.Groups)
                        {
                            if (matchCount == 0)
                            {
                                matchValues.Add("[REMOVED]");
                            }
                            else
                            {
                                matchValues.Add(thisGroup.Value.ToString());
                            }
                            matchCount++;
                        }

                        return DoRedirect(String.Format(redirectItem.DestURL, matchValues.ToArray()), redirectItem);
                    }
                }
                else if (aspxErrorPath == redirectItem.RequestedURL)
                {
                    return DoRedirect(redirectItem.DestURL, redirectItem);
                }
            }

            throw new HttpException(404, "NotFound");
        }

        private RedirectResult DoRedirect(string redirectURL, RedirectItemEntry redirectItem)
        {
            redirectURL += redirectURL.Contains("?") ? "&loopstopper=1" : "?loopstopper=1";

            if (redirectItem.RedirectType == "301")
            {
                return RedirectPermanent(redirectURL);
            }
            else
            {
                return Redirect(redirectURL);
            }
        }

        private RedirectItemEntry CreateRedirectItemEntries(RedirectPart redirectPart)
        {
            return new RedirectItemEntry
            {
                RedirectEntryId = redirectPart.Id,
                RequestedURL = redirectPart.RequestedUrl,
                DestURL = redirectPart.DestUrl,
                UseRegex = redirectPart.UseRegex,
                RedirectType = redirectPart.RedirectType,
                ProcessOrder = redirectPart.ProcessOrder
            };
        }

        public Localizer T { get; set; }
    }
}
